<template>
  <el-drawer
      ref="drawerRef"
      :model-value="roleMenuBindVisible"
      :with-header="false"
      size="40%"
      @closed="drawerClose"
  >
    <div class="container">
      <div class="table-header">
        <div style="margin-bottom: 15px; font-size: 16px; color: darkgrey; font-weight: bold">
          为角色:
          <el-text style="font-size: 18px" type="primary" size="large">{{ roleName }}</el-text>
          配置菜单权限
        </div>
      </div>
      <el-tree
          ref="permissionsTree"
          :icon="Menu"
          style="max-width: 700px"
          :data="allMenuData"
          show-checkbox
          node-key="id"
          @check-change="checkChange"
          :render-after-expand="false"
          :props="{ label:  'menuName', children: 'subMenuList' }">
        <template #default="{ node, data }">
          <div class="custom-tree-node">
            <span>{{ node.label }}</span>
            <el-checkbox-group v-if="data.fatherNumber !== 'M'" v-model="data.permissions">
              <el-checkbox label="查询" :value="1"/>
              <el-checkbox label="新增" :value="2"/>
              <el-checkbox label="更新" :value="4"/>
              <el-checkbox label="删除" :value="8"/>
              <el-checkbox label="导出" :value="9"/>
            </el-checkbox-group>
          </div>
        </template>
      </el-tree>
      <div class="pagination" style="justify-content: start">
        <el-button @click="handleCancel">
          取消
        </el-button>
        <el-button type="primary" @click="handleBind">
          确定
        </el-button>
      </div>
    </div>
  </el-drawer>
</template>

<script setup>
import {onMounted, ref, useTemplateRef} from 'vue';
import menuRequest from "@/api/sys/MenuApi.js";
import {Menu} from '@element-plus/icons-vue';
import {ElMessage} from "element-plus";

const emit = defineEmits(['update:roleMenuBindVisible']);
const props = defineProps({
  roleMenuBindVisible: {
    required: true,
    type: Boolean,
    default: false
  },
  roleId: {
    required: true,
    type: Number,
    default: 0
  },
  roleName: {
    required: true,
    type: String,
    default: ''
  },
  menuId: {
    required: true,
    type: Number,
    default: 0
  }
});

let allMenuData = ref([]);
let treeRef = useTemplateRef('permissionsTree');
let drawerRef = useTemplateRef('drawerRef');

onMounted(() => {
  getAllMenuList();
});

const getAllMenuList = () => {
  menuRequest.queryMenuList({
    menuId: props.menuId
  }).then(res => {
    allMenuData.value = res.data;
    getMenuListByRoleId(props.roleId);
  });
}

const getMenuListByRoleId = (roleId) => {
  menuRequest.queryMenuListByRoleId({
    roleId,
    menuId: props.menuId
  }).then(res => {
    allMenuData.value = mergePermissionsToAllMenu(allMenuData.value, res.data);
    handleCheck(res.data);
  });
}

const handleBind = () => {
  let checkedNodes = treeRef.value?.getCheckedNodes(false, true)
      .map(item => {
        return {menuId: item.id, permissions: item.permissions.filter(item => !isNaN(item)).join(',')}
      });
  menuRequest.updateRoleMenuByRoleId(props.roleId, {menuIds: checkedNodes, menuId: props.menuId})
      .then(() => {
        drawerRef.value?.handleClose();
        ElMessage({
          type: 'success',
          message: '操作成功',
        });
      });
}

const handleCancel = () => {
  drawerRef.value?.handleClose();
}

const handleCheck = (roleMenuData) => {
  treeRef.value?.setCheckedKeys(getCheckedKeys(roleMenuData), false);
}

const drawerClose = () => {
  emit('update:roleMenuBindVisible', false);
}

const getCheckedKeys = (roleMenuData) => {
  let keys = [];
  roleMenuData.forEach(item => {
    if (item.fatherNumber !== 'M') {
      keys.push(item.id);
    }
    if (item.subMenuList && item.subMenuList.length > 0) {
      keys = keys.concat(getCheckedKeys(item.subMenuList));
    }
  });
  return keys;
}

const checkChange = (node, isChecked) => {
  if (node.fatherNumber !== 'M') {
    if (isChecked) {
      node.permissions = node.permissions || [1, 2, 4, 8];
    } else {
      node.permissions = [];
    }
  }
}

const mergePermissionsToAllMenu = (allMenus, roleMenus) => {
  const roleMap = {};
  const buildRoleMap = (nodes) => {
    nodes.forEach(node => {
      roleMap[node.id] = node.permissions || [];
      if (node.subMenuList) {
        buildRoleMap(node.subMenuList);
      }
    });
  };
  buildRoleMap(roleMenus);
  const setPermissions = (nodes) => {
    return nodes.map(node => {
      node.permissions = String(roleMap[node.id]).split(',').map(item => Number(item)) || [];
      if (node.subMenuList) {
        node.subMenuList = setPermissions(node.subMenuList);
      }
      return node;
    });
  };

  return setPermissions(allMenus);
};

</script>

<style scoped>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>
